/*****************************************************************
 *仿佛兮若轻云之蔽月，飘飘兮若流风之回雪
 *@filename DBExcelMapper.java
 *@author WYY
 *@date 2013年11月24日
 *@copyright (c) 2013  wyyft@163.com All rights reserved.
 *****************************************************************/
package com.featherlike.feather.generator.excel;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.featherlike.feather.generator.entity.Column;
import com.featherlike.feather.generator.entity.Table;
import com.featherlike.framework.common.util.StringUtil;

public abstract class ExcelMapper {
    protected static final Logger LOG = LoggerFactory
            .getLogger(ExcelMapper.class);
    private static final int SHEET_INDEX_0 = 0;
    private static final int COLUMN_INDEX_0 = 0;
    private static final int COLUMN_INDEX_1 = 1;
    private static final int COLUMN_INDEX_2 = 2;
    private static final int COLUMN_INDEX_3 = 3;
    private static final int COLUMN_INDEX_4 = 4;
    private static final int COLUMN_INDEX_5 = 5;
    private static final int COLUMN_INDEX_6 = 6;
    private static final int COLUMN_INDEX_7 = 7;
    private static final int COLUMN_INDEX_8 = 8;
    private static final int COLUMN_INDEX_9 = 9;
    private static final int COLUMN_INDEX_10 = 10;
    private static final int COLUMN_INDEX_11 = 11;

    public Map<Table, List<Column>> createTableMap(String inputPath) {
        Map<Table, List<Column>> tableMap = new LinkedHashMap<Table, List<Column>>();
        try {
            init(inputPath);
            String moduleName = getModuleName();
            for (int i = 1; i < getNumberOfSheets(); i++) {
                initSheet(i);
                String tableName = moduleName + '_'
                        + getSheetName().toLowerCase();
                String tablePK = "";
                List<Column> columnList = new ArrayList<Column>();
                for (int row = 1; row < getNumOfRows(); row++) {
                    String name = getCellValue(COLUMN_INDEX_0, row);
                    if (StringUtil.isBlank(name)) {
                        break;
                    }
                    String type = getCellValue(COLUMN_INDEX_1, row);
                    String length = getCellValue(COLUMN_INDEX_2, row);
                    String precision = getCellValue(COLUMN_INDEX_3, row);
                    String notnull = getCellValue(COLUMN_INDEX_4, row);
                    String pk = getCellValue(COLUMN_INDEX_5, row);
                    String comment = getCellValue(COLUMN_INDEX_6, row);
                    String listPage = getCellValue(COLUMN_INDEX_7, row);
                    String queryPage = getCellValue(COLUMN_INDEX_8, row);
                    String modifyPage = getCellValue(COLUMN_INDEX_9, row);
                    String asLink = getCellValue(COLUMN_INDEX_10, row);
                    String dictType = getCellValue(COLUMN_INDEX_11, row);
                    Column column = new Column(name, type, length, precision,
                            notnull, pk, comment, listPage, queryPage,
                            modifyPage, asLink, dictType);
                    columnList.add(column);
                    if (StringUtil.isNotBlank(pk) && ("Y".equals(pk))) {
                        tablePK = name;
                    }
                }
                tableMap.put(new Table(tableName, tablePK), columnList);
            }
            distroy();
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
        return tableMap;
    }

    private String getModuleName() {
        initSheet(SHEET_INDEX_0);
        return getSheetName().toLowerCase().trim();
    }

    abstract void initSheet(int index);

    abstract String getSheetName();

    abstract int getNumberOfSheets();

    abstract int getNumOfRows();

    abstract String getCellValue(int column, int row);

    abstract void init(String inputPath) throws Exception;

    abstract void distroy();
}